-
-
Notifications
You must be signed in to change notification settings - Fork 48
🐛 Fix CtrlOp::getBodyUnitary() for operations with parameters #1464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughSummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughThis PR adds two PR references to CHANGELOG.md within the MLIR dialect infrastructure section and introduces a new unit test case Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used🧠 Learnings (16)📓 Common learnings📚 Learning: 2026-01-08T22:56:09.502ZApplied to files:
📚 Learning: 2025-12-05T17:45:37.602ZApplied to files:
📚 Learning: 2026-01-10T18:49:44.352ZApplied to files:
📚 Learning: 2025-10-14T14:37:38.047ZApplied to files:
📚 Learning: 2025-12-08T23:58:09.648ZApplied to files:
📚 Learning: 2025-12-08T12:44:05.883ZApplied to files:
📚 Learning: 2025-10-09T13:13:51.224ZApplied to files:
📚 Learning: 2025-12-08T14:55:43.899ZApplied to files:
📚 Learning: 2026-01-12T12:05:56.683ZApplied to files:
📚 Learning: 2026-01-07T12:29:02.062ZApplied to files:
📚 Learning: 2026-01-10T16:28:41.975ZApplied to files:
📚 Learning: 2026-01-07T12:29:16.380ZApplied to files:
📚 Learning: 2026-01-10T16:07:55.896ZApplied to files:
📚 Learning: 2025-12-08T23:44:39.930ZApplied to files:
📚 Learning: 2025-12-17T11:32:45.843ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
🔇 Additional comments (3)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
burgholzer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not 100% that this is the right solution here.
The IR for parasitized operations shouldn't actually pass verification because the verifier of the QC) CtrlOp asserts that any CtrlOp only contains two operations (the UnitaryOp and the yield). I am surprised that we are not hitting this so far.
I assume that we should be running mlir::verify in the compiler pipeline tests on all circuits constructed by any builders or produced by the compiler.
I would argue that the real fix here is to modify the builders so that they directly insert the constant operations in the highest scope possible.
This might prevent us from ever declaring the CtrlOp as IsolatedFromAbove, which might not be feasible anyway because it was (and needs to be) valid to use a parameter in a controlled rotation gate that was defined outside of the region.
My request here would be two-fold
- Can we fix the builders instead of iterating over the control op body?
- Can we ensure that the IR in our tests is verified (especially in the compiler pipeline tests)?
What's the argument against just moving the parameter into the body? Wouldn't that also simplify optimizations involving the control modifier since it actually is
Do you have an idea how we could define this "highest scope possible"? Because wouldn't that be the
I guess that should be possible, but how do we want to handle that in actual non-test code? Running a verification after every optimization would probably cause a lot of unnecessary overhead. Or do we just assume that the optimizations are all doing valid transformations? Because it could also happen that "optimization 1" will cause an invalid IR which "optimization 2" will transform back into a valid IR but with a different functionality than intended and thus only the final IR check might be insufficient? |
There might be multiple uses of the same parameter across operations and we do not want to bury these in (potentially nested) modifier regions.
The canonicalization pipeline that we employ as part of the compiler pipeline already employs this "bubbling up as high as possible". You can see that in the various stages of the IR in the tests. This should also give you an indication of where the appropriate place for the constant ops is. I believe it should be the first regions with with IsolatedFromAbove trait (which might be the
See https://mlir.llvm.org/getting_started/DeveloperGuide/#ir-should-be-valid-before-and-after-each-pass and https://mlir.llvm.org/getting_started/DeveloperGuide/#ir-verifier |
Thanks for the links! I need to do some reading and experimenting, but there definitely is something broken here because Edit: I also made sure that the test case I added will fail without my proposed fix, that is why I'm sure it currently is broken Edit Nr. 2: Ah, I think I got what you're saying - in the actual code it's not an issue but just the test code because it's running without the verifier at the moment. I'll check out adding the verifier to the broken test case |
|
What would be good is to reduce this PR to a reproducer of the issues you are seeing so that we have them as logs in the CI. We are currently not seeing them in the compiler pipeline tests, but this could very much be due to us not having a test with controlled rotations (which we should add on that case). |
cc9488f to
5fae654
Compare
Thanks.
Yeah. Seams like a bug in the builder to me. Or in our definition of a valid control modifier, but I am heavily leaning to the bug. @denialhaag could you maybe briefly take a look at this? |
I am all but certain that the issue is that we are not resolving the core/mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp Lines 227 to 234 in 0089f7d
Instead, the core/mlir/lib/Dialect/QC/IR/Operations/StandardGates/RXOp.cpp Lines 22 to 26 in 0089f7d
I think we could simply call the |
Indeed, that seems to be the main issue and a nice solution to the issue! Thanks for quickly getting back to this. |


Description
While debugging test cases in #1426, I finally figured out why
CtrlOp::getBodyUnitary()sometimes returned an invalidUnitaryOpInterface.Whenever an operation has at least one parameter, the first operation in the modifier's body will be a
arith.constantand not the unitary operation like it is currently assumed in the function.This PR resolves this by iterating over all operations in the body and only returning when the first
UnitaryOpInterfaceoperation has been found or there is none.It affects all
crx,crzz,cu, ... operations.Required for #1426
Checklist: